package demoMod.anm2editor.ui;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import demoMod.anm2editor.fonts.FontKeys;
import demoMod.anm2editor.interfaces.ReloadStringsSubscriber;
import demoMod.anm2editor.localization.LocalizedStrings;
import demoMod.anm2editor.model.Operation;
import demoMod.anm2editor.model.Project;
import demoMod.anm2editor.model.SpriteSheet;
import demoMod.anm2editor.utils.IdGenerator;
import demoMod.gdxform.core.AbstractAction;
import demoMod.gdxform.core.FormManager;
import demoMod.gdxform.enums.GFrameCloseStrategy;
import demoMod.gdxform.enums.GFrameWindowStyle;
import demoMod.gdxform.helpers.FontHelper;
import demoMod.gdxform.ui.*;

import java.io.File;
import java.util.List;

public class RegionManager extends GFrame implements ReloadStringsSubscriber {
    public static final String ID = "RegionManager";
    private final GScrollPane scrollPane;
    private final SpriteSheetList spriteSheetList = new SpriteSheetList();
    private static List<String> strings;

    public RegionManager() {
        super(Gdx.graphics.getWidth() * 0.8F + 2, Gdx.graphics.getHeight() * 0.2F + 23, Gdx.graphics.getWidth() * 0.2F - 4, Gdx.graphics.getHeight() * 0.8F - 47, FontHelper.getFont(FontKeys.SIM_HEI_14), GFrameWindowStyle.CLOSE_BUTTON_ONLY, false);
        if (strings == null) {
            strings = LocalizedStrings.getStrings(ID);
        }
        setId(ID);
        setTitle(strings.get(0));
        setResizable(true);
        setCloseStrategy(GFrameCloseStrategy.HIDDEN_ON_CLOSE);
        scrollPane = new GScrollPane(0, 0, getWidth(), getHeight() - getBannerHeight() - 20, getWidth(), getHeight()) {
            @Override
            public float getWidth() {
                return RegionManager.this.getWidth();
            }
        };
        GVScrollBar vScrollBar = new GVScrollBar(0, 0, 10, getHeight() - getBannerHeight());
        scrollPane.setVScrollBar(vScrollBar);
        addElement(scrollPane);

        spriteSheetList.setCellHeight(Gdx.graphics.getHeight() * 0.05F);
        scrollPane.addElement(spriteSheetList);
        LocalizedStrings.subscribe(this);
    }

    public SpriteSheetList getSpriteSheetList() {
        return spriteSheetList;
    }

    public GScrollPane getScrollPane() {
        return scrollPane;
    }

    @Override
    public boolean clickDown(int screenX, int screenY, int button) {
        if (super.clickDown(screenX, screenY, button)) {
            return true;
        }
        if (button == Input.Buttons.RIGHT && (float)screenX >= this.getX(true) && (float)screenX <= this.getX(true) + this.getWidth() && (float)(Gdx.graphics.getHeight() - screenY) >= this.getY(true) && (float)(Gdx.graphics.getHeight() - screenY) <= this.getY(true) + this.getHeight()) {
            GMenuList menuList = new GMenuList();
            menuList.setWidth(150.0F);
            menuList.setX(screenX);
            menuList.setY(Gdx.graphics.getHeight() - screenY);
            List<String> fileSelectWindowStrings = LocalizedStrings.getStrings("FileSelectWindow");
            GMenuItem newSprite = new GMenuItem(menuList.getWidth(), menuList.getMenuItemHeight(), strings.get(1) + "...", FontHelper.getFont(FontKeys.SIM_HEI_14)) {
                @Override
                public void onClick() {
                    GFileSelectWindow fileSelectWindow = new GFileSelectWindow(FontHelper.getFont(FontKeys.SIM_HEI_14));
                    fileSelectWindow.setTitle(strings.get(2));
                    fileSelectWindow.setConfirmText(fileSelectWindowStrings.get(0));
                    fileSelectWindow.setCancelText(fileSelectWindowStrings.get(1));
                    fileSelectWindow.setBackText(fileSelectWindowStrings.get(2));
                    fileSelectWindow.setFileFilter(file -> file.isDirectory() || file.getName().endsWith(".png") || file.getName().endsWith(".PNG"));
                    fileSelectWindow.setPath(Project.currentProject.getFilePath());
                    fileSelectWindow.setConfirmCallback((path, selectedFiles) -> {
                        if (!selectedFiles.isEmpty()) {
                            String filepath = selectedFiles.get(0).getAbsolutePath();
                            Texture region = new Texture(Gdx.files.absolute(filepath));
                            SpriteSheet spriteSheet = new SpriteSheet();
                            spriteSheet.setSprite(region);
                            spriteSheet.setPath(filepath.replace(Project.currentProject.getFilePath() + File.separator, ""));
                            spriteSheet.loadAtlasData();
                            int id = IdGenerator.nextSpriteSheetId();
                            Project.currentProject.addSpriteSheet(id, spriteSheet);
                            SpriteSheetItem item = new SpriteSheetItem(FontHelper.getFont(FontKeys.SIM_HEI_14));
                            item.setSpriteSheet(spriteSheet);
                            item.setId(Integer.toString(id));
                            spriteSheetList.addItem(item);
                            if (spriteSheetList.getElements().size() * spriteSheetList.getCellHeight() > scrollPane.getPlainHeight()) {
                                scrollPane.setPlainHeight(scrollPane.getPlainHeight() + spriteSheetList.getCellHeight());
                            }
                            Operation operation = new Operation() {
                                @Override
                                public void undo() {
                                    IdGenerator.setSpriteSheetId(id);
                                    Project.currentProject.removeSpriteSheet(id);
                                    spriteSheetList.removeItem(item);
                                    actionManager.addToSequenceBot(new AbstractAction.Builder().setActionBody(duration -> {
                                        if (Project.currentProject.getSpriteSheets().size() * spriteSheetList.getCellHeight() < scrollPane.getPlainHeight()
                                                && scrollPane.getPlainHeight() - spriteSheetList.getCellHeight() > scrollPane.getHeight()) {
                                            scrollPane.setPlainHeight(scrollPane.getPlainHeight() - spriteSheetList.getCellHeight());
                                        }
                                        return true;
                                    }).build());
                                    spriteSheet.dispose();
                                }

                                @Override
                                public void redo() {
                                    IdGenerator.setSpriteSheetId(id + 1);
                                    Texture region = new Texture(Gdx.files.absolute(filepath));
                                    spriteSheet.setSprite(region);
                                    Project.currentProject.addSpriteSheet(id, spriteSheet);
                                    spriteSheetList.addItem(item);
                                    if (spriteSheetList.getElements().size() * spriteSheetList.getCellHeight() > scrollPane.getPlainHeight()) {
                                        scrollPane.setPlainHeight(scrollPane.getPlainHeight() + spriteSheetList.getCellHeight());
                                    }
                                }
                            };
                            operation.setName(strings.get(3));
                            ((HistoryPanel) FormManager.getInstance().getContainerById(HistoryPanel.ID)).addOperation(operation);
                        }
                    });
                }
            };
            if (Project.currentProject.getFilePath() == null) {
                newSprite.setEnabled(false);
            }
            newSprite.setSplitLine(false);
            menuList.addElement(newSprite);
            FormManager.getInstance().addContainer(menuList);
            FormManager.getInstance().moveToTop(menuList);
            return true;
        }
        return false;
    }

    @Override
    public void onReloadStrings() {
        strings = LocalizedStrings.getStrings(ID);
        setTitle(strings.get(0));
    }
}
